import path from 'path';
import { nanoid } from 'nanoid';
import { WindowService } from './index';
import { writeNewFile } from '@e/methods/file';
import { FileExistsOperation } from '@type/file';
import { Mode1Data } from '@type/main-modeData';
import { downloadFile } from '@e/methods/download';
import { ImageInfo } from '@type/main-windowObject';
import { extractFilenameFromURL } from '@e/methods/url';
import { getImageType, ImageTypeResult } from '@e/methods/image';
import { ImageCacheDataValue, ImageDownloadInfo, ImageDownloadResult } from '@type/WindowService';

/**
 * 生成下载信息
 */
export function generateImageDownloadInfo(data: Mode1Data, imageInfo: ImageInfo[]): ImageDownloadInfo[] {
	// 没有文件名的处理
	function notFilename(obj: ImageDownloadInfo) {
		obj.filename = nanoid(); // 生成一个随机文件名
		obj.notExt = true;

		return obj;
	}

	// 统一保存处理
	function unifiedSaveFn() {
		return imageInfo
			.filter((i) => i.type === 'url' && !i.exist)
			.map((item) => {
				let infoItem: ImageDownloadInfo = {
					url: item.target,
					savePath: data.unifiedSavePath,
					filename: extractFilenameFromURL(item.target) || '',
				};

				// 如果没能从url中提取到文件名的处理
				if (!infoItem.filename) {
					infoItem = notFilename(infoItem);
				}

				return infoItem;
			});
	}

	// 分别保存处理
	function separatelySaveFn() {
		return data.separatelySavePaths.reduce((t, item) => {
			const arr = item.children.map((s_item) => {
				let infoItem: ImageDownloadInfo = {
					url: s_item.target,
					savePath: item.dirPaht,
					filename: extractFilenameFromURL(s_item.target) || '',
				};

				if (!infoItem.filename) {
					// 如果没能从url中提取到文件名的处理
					infoItem = notFilename(infoItem);
				}

				return infoItem;
			});

			t.push(...arr);

			return t;
		}, [] as ImageDownloadInfo[]);
	}

	switch (data.saveMode) {
		case 'unifiedSave':
			return unifiedSaveFn();
		case 'separatelySave':
			return separatelySaveFn();
	}
}

/**
 * 批量下载图片
 */
export async function downloadImages(this: WindowService, imageDownloadInfo: ImageDownloadInfo[]) {
	const results: ImageDownloadResult[] = [];
	let messageId: number;
	let filename: string;
	let fileExistsOperation: FileExistsOperation | undefined;

	// 发送错误消息
	const snedErrorMessage = (str: string) => {
		this.sendMessage('update', 'error', str, messageId);
	};
	// 发送警告消息
	const snedWarningMessage = (str: string) => {
		this.sendMessage('update', 'warning', str, messageId);
	};
	// 发送成功消息
	const sendSuccessMessage = () => {
		this.sendMessage('update', 'success', `下载成功：${filename}`, messageId);
	};
	// 发送下载进度消息
	const sendProgressMessage = (progress: number) => {
		this.sendMessage('update', 'info', `正在下载：${filename} ${progress}%`, messageId);
	};

	// 循环下载
	for (let i = 0; i < imageDownloadInfo.length; i++) {
		const item = imageDownloadInfo[i];
		let downloadResult = false;
		filename = item.filename;

		messageId = this.sendMessage('insert', 'info', `正在下载：${filename}`);

		try {
			let buf: Buffer;
			let typeResult: ImageTypeResult | undefined;

			// 如果在缓存中直接拿
			if (this.imageCacheData.has(item.url)) {
				const cache = this.imageCacheData.get(item.url) as ImageCacheDataValue;

				buf = cache.buffer;
				typeResult = { ext: cache.ext, mime: cache.mime };
			} else {
				// 下载图片
				buf = await downloadFile(item.url, sendProgressMessage);
				// 获取图片类型
				typeResult = getImageType(buf);
			}

			if (typeResult) {
				// 没有扩展名的的处理
				if (item.notExt) {
					filename = filename + '.' + typeResult.ext;
				}
				// 写入路径
				const writePath = path.join(item.savePath, filename);
				// 写入文件
				const writeResult = await writeNewFile(this.window, writePath, buf, undefined, fileExistsOperation);
				// 当文件存在时用户是否选择了记住我的选择
				if (writeResult.rememberMyChoice) {
					fileExistsOperation = writeResult.fileExistsOperation;
				}

				if (writeResult.success) {
					// 写入成功
					sendSuccessMessage();
					downloadResult = true;
				} else {
					switch (writeResult.type) {
						case 'error': // 写入发生了错误
							snedErrorMessage(`写入失败：${filename}\n写入路径：${writePath}\n${writeResult.error}`);
							break;
						case 'cancel':
							snedWarningMessage(`文件已存在，用户取消了写入\n冲突路径：${writePath}`);
							break;
					}
				}
			} else {
				snedErrorMessage(`${filename} 不是图片文件\n下载地址：${item.url}`);
			}
		} catch (error) {
			let msg = '未知错误';
			if (error) msg + '：' + error.toString();
			snedErrorMessage(msg);
		} finally {
			// 将下载结果放入结果集
			results.push({
				...item,
				result: downloadResult,
			});
		}
	}

	return results;
}
